package com.atguigu.tingshu.album.job;

import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author: atguigu
 * @create: 2024-10-30 14:44
 */
@Slf4j
@Component
public class RebuildBloomFilterTask {


    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    /**
     * 每3个月重建一次布隆过滤器
     */
    @Scheduled(cron = "0 0 2 * 1/3 ?")
    //@Scheduled(cron = "0/10 * * * * ?")
    public void rebuildBloomFilter() {
        log.info("开始重建布隆过滤器");
        //1.获取原有布隆过滤器对象
        RBloomFilter<Long> oldBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        long expectedInsertions = oldBloomFilter.getExpectedInsertions();
        long count = oldBloomFilter.count();
        //2.判断布隆过滤器中元素数量是否大于期望数据规模
        if (count >= expectedInsertions) {
            //3.新建布隆过滤器 原有名称:new 期望数据规模设置为原来2倍
            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER+":new");
            newBloomFilter.tryInit(expectedInsertions*2, oldBloomFilter.getFalseProbability());

            //4.查询现有审核通过专辑ID，将ID存入到新布隆过滤
            LambdaQueryWrapper<AlbumInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS);
            lambdaQueryWrapper.select(AlbumInfo::getId);
            List<AlbumInfo> albumInfoList = albumInfoMapper.selectList(lambdaQueryWrapper);
            if(CollectionUtil.isNotEmpty(albumInfoList)){
                for (AlbumInfo albumInfo : albumInfoList) {
                    newBloomFilter.add(albumInfo.getId());
                }
            }
            //5.删除原有布隆过滤器
            oldBloomFilter.delete();
            //6.重命名布隆过滤器
            newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
        }
    }
}
